package org.fastsyncer.parser.webservice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.fastsyncer.common.constant.ConnectorConstant;
import org.fastsyncer.common.entity.Mapping;
import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.common.entity.WebServiceConfig;
import org.fastsyncer.common.util.JsonUtil;
import org.fastsyncer.connector.webservice.WebServiceConnector;
import org.fastsyncer.parser.framework.Parser;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class WebserviceParser implements Parser {

    private static volatile WebserviceParser instance = null;

    private WebserviceParser() {
    }

    public static WebserviceParser getInstance() {
        if (null == instance) {
            synchronized (WebserviceParser.class) {
                if (null == instance) {
                    instance = new WebserviceParser();
                }
            }
        }
        return instance;
    }

    private static Logger logger = LoggerFactory.getLogger(WebserviceParser.class);

    private WebServiceConnector service = WebServiceConnector.getInstance();
    
    @Override
    public List<Map<String, Object>> batchQuery(MappingTask mappingTask, Integer startPos, Integer endPos) throws Exception {
        return null;
    }

    @Override
    public Integer[] batchInsert(MappingTask mappingTask, List<Map<String, Object>> rows, Integer[] pos, Queue<JSONObject> reasonQuene) throws Exception {
        // 批量条数
        int size = rows.size();
        // 总数和成功数
        int total = size;
        int success = 0;
        try {
            // 1.同步数据源、目标源属性
            Mapping targetMapping = mappingTask.getTargetMapping();
            WebServiceConfig config = (WebServiceConfig) targetMapping.getConfig();

            Map<String, Object> res;
            for (Map<String, Object> map : rows) {
                res = new HashMap<String, Object>();
                res.put("EVENTTYPE", ConnectorConstant.OPERTION_INSERT);
                res.put("DATA", map);
                // 2.转换为JSON字符串
                String objToJson = JsonUtil.objToJson(res);
                logger.info(objToJson);

                // 3.推送目标源
                service.send(config.getUrl(), config.getMethod(), objToJson);
                success++;
            }
        } catch (Exception e) {
            try {
                // 记录错误信息
                JSONObject err = new JSONObject();
                if (pos != null && pos.length == 2) {
                    err.put("startPos", pos[0]);
                    err.put("endPos", pos[1]);
                }
                err.put("message", e.getMessage());
                reasonQuene.offer(err);
            } catch (JSONException e1) {
                logger.error("When logging an error message: Converts a JSONObject exception!");
            }
        }
        return new Integer[] { total, success };
    }

    @Override
    public boolean insert(MappingTask mappingTask, Map<String, Object> row) throws Exception {
        return this.send(mappingTask, ConnectorConstant.OPERTION_INSERT, row);
    }

    @Override
    public boolean update(MappingTask mappingTask, Map<String, Object> row) throws Exception {
        return this.send(mappingTask, ConnectorConstant.OPERTION_UPDATE, row);
    }

    @Override
    public boolean delete(MappingTask mappingTask, Map<String, Object> row) throws Exception {
        return this.send(mappingTask, ConnectorConstant.OPERTION_DELETE, row);
    }

    /**
     * 推送目标源
     * 
     * @param mappingTask
     * @param eventType
     *            同步事件
     * @param row
     *            同步数据
     * @return 执行结果true/false
     * @throws Exception
     */
    private boolean send(MappingTask mappingTask, String eventType, Map<String, Object> row) throws Exception {
        // 1.同步数据源、目标源属性
        Mapping targetMapping = mappingTask.getTargetMapping();

        // 3.转换为JSON字符串
        Map<String, Object> res = new HashMap<String, Object>();
        res.put("EVENTTYPE", eventType);
        res.put("DATA", row);
        String objToJson = JsonUtil.objToJson(res);
        logger.info(objToJson);

        // 4.推送目标源
        WebServiceConfig config = (WebServiceConfig) targetMapping.getConfig();
        Object r = service.send(config.getUrl(), config.getMethod(), objToJson);
        logger.info(r.toString());
        return true;
    }
}
